package cn.duhengkui.national.poi.word;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.xwpf.usermodel.IBody;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFHeaderFooter;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.apache.poi.xwpf.usermodel.XWPFTable;
import org.apache.poi.xwpf.usermodel.XWPFTableCell;
import org.apache.poi.xwpf.usermodel.XWPFTableRow;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRPr;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.STMerge;

import cn.duhengkui.national.poi.exception.WordGenException;
import cn.duhengkui.national.poi.utils.ChangeBean;
import cn.duhengkui.national.poi.word.model.ListParamModel;
import cn.duhengkui.national.poi.word.model.TableBaseModel;
import cn.duhengkui.national.poi.word.model.WordImgModel;


/**   
 * <table border="1">
 *	<tr><td>包名称：</td><td>cn.duhengkui.national.poi.word</td></tr>
 *	<tr><td>类名称：</td><td>POIWordUtil</td></tr>
 *	<tr><td>类描述：</td><td>word生成主方法</td></tr>
 *	<tr><td>创建人：</td><td>杜恒奎</td></tr>
 *  <tr><td>创建时间：</td><td>2018年7月11日/下午2:57:28</td></tr> 
 *  <tr><td>版本：</td><td>1.0.0</td></tr>
 * </table>   
 *     
 */
public class POIWordUtil {

	
	public static final String START_MARK = "{";
	public static final String END_MARK = "}";
	
	public static final String TABLE_COL_PREFIX = "$";
	public static final String TABLE_LIST_PREFIX = "%";
	public static final String TABLE_COL_START_MARK = TABLE_COL_PREFIX + START_MARK;
	public static final String TABLE_LIST_START_MARK = TABLE_LIST_PREFIX + START_MARK;

	public static final String RUNNING_PREFIX = "#";
	public static final String RUNNING_START_MARK = RUNNING_PREFIX + START_MARK;

	public static final String PIC_PREFIX = "&";
	public static final String PIC_START_MARK = PIC_PREFIX + START_MARK;
	
	public static final String LIST_START_FIRST = "/";
	public static final String LIST_START_SECOND = "#";
	
	public static final String LIST_START_MARK= LIST_START_FIRST + LIST_START_SECOND;
	public static final String LIST_END_MARK = LIST_START_SECOND + LIST_START_FIRST;

	public static final String LISTPARAM_PREFIX = "@";
	public static final String LISTPARAM_START_MARK = LISTPARAM_PREFIX + START_MARK;

	private ThreadLocal<Integer> picIndex = new ThreadLocal<>();


	/**
	* @Title: processWord
	* @Description: 根据模板生成word
	* @param tmplateIs
	* @param genWordOs
	* @param whereClause
	* @param tableParams
	* @param imgs
	* @param paragraphParamMap
	* @throws IOException
	* @return void
	*/ 
	
	public void processWord(InputStream tmplateIs, OutputStream genWordOs,
			Map<String, Object> whereClause, Map<String, ListParamModel> tableParamsMap,
			Map<String, List<WordImgModel>> imgs,
			Map<String, ListParamModel> paragraphParamMap) throws IOException {

		CustomXWPFDocument document = new CustomXWPFDocument(tmplateIs);
		List<XWPFParagraph> paragraphs = document.getParagraphs();
		List<XWPFTable> tables = document.getTables();
		picIndex.set(document.getAllPictures().size());
		genTables(tables, tableParamsMap,paragraphParamMap,whereClause);
		insertParagraph(document, genListParagraph(paragraphs, paragraphParamMap,whereClause));
		for (int i = 0; i < paragraphs.size(); i++) {
			XWPFParagraph paragraph = paragraphs.get(i);
			genPicParagraph(document, paragraph, imgs);
			genRunningParagraph(paragraph, whereClause);

		}

		
		document.write(genWordOs);

	}


	/**
	* @Title: genListParagraph
	* @Description: word中需要段落列表循环，生成匹配列表
	* @param paragraph
	* @param paragraphParamMap
	* @return Map<XWPFParagraph, List<String>> 返回插入列表
	*/ 
	@SuppressWarnings("unchecked")
	private Map<XWPFParagraph, List<String>> genListParagraph(List<XWPFParagraph> paragraphs,Map<String, ListParamModel> paragraphParamMap,Map<String, Object> whereClause){
		boolean isPara = false;
		String listkey = null;
		String listPara = "";

		Map<XWPFParagraph, List<String>> insertParaMap = new HashMap<XWPFParagraph, List<String>>();
		for (int i = 0; i < paragraphs.size(); i++) {
			XWPFParagraph paragraph = paragraphs.get(i);
			genRunningParagraph(paragraph, whereClause);
			if (paragraph.getText().indexOf(LIST_START_MARK) >= 0) {
				listkey = paragraph.getText().substring(
						paragraph.getText().indexOf(LIST_START_MARK)
								+ LIST_START_MARK.length(),
						paragraph.getText().indexOf(":"));
				isPara = true;
			}
			if (isPara) {
				if (paragraph.getText().indexOf(LIST_START_MARK) >= 0) {
					listPara += paragraph.getText().substring(
							paragraph.getText().indexOf(LIST_START_MARK)
									+ LIST_START_MARK.length()
									+ listkey.length() + 1);
				} else {
					listPara += paragraph.getText();
				}
				if (listPara.indexOf(LIST_END_MARK) >= 0) {
					isPara = false;
					listPara = listPara.substring(0,
							listPara.indexOf(LIST_END_MARK));

					List<Object> objectList = null;
					List<String> valueList = new ArrayList<String>();
					if (paragraphParamMap != null
							&& paragraphParamMap.get(listkey) != null) {
						objectList = (List<Object>) paragraphParamMap
								.get(listkey).getParamList();
						Class<?> clazz = paragraphParamMap.get(listkey)
								.getClazz();
						Field[] fields = clazz.getDeclaredFields();
						for (int k = 0; k < objectList.size(); k++) {
							String re = new String(listPara);
							Object object = objectList.get(k);
							for (int end = 0, start; ((start = re.toString()
									.indexOf(LISTPARAM_START_MARK,
											end)) >= 0);) {
								end = re.toString().indexOf(END_MARK,
										start);
								String key = re.substring(
										start + LISTPARAM_START_MARK.length(),
										end);
								Object value = null;
								for (int j = 0; j < fields.length; j++) {
									try {
										if (fields[j].getName().equals(key)) {

											Method getter = clazz
													.getDeclaredMethod(
															"get" + ChangeBean
																	.captureName(
																			key));
											if (object != null) {
												value = getter.invoke(object);
												break;
											}
										}
									} catch (Exception e) {
										throw new WordGenException(e);
									}
								}
								if (value == null) {
									throw new WordGenException("Property '"
											+ key + "' was not provided.");
								};
								re = new StringBuffer(re)
										.replace(start,
												end + END_MARK
														.length(),
										value.toString()).toString();
								end -= (key.length()
										+ LISTPARAM_START_MARK.length());
							}
							valueList.add(re);
						}
					}
					insertParaMap.put(paragraph, valueList);
					listPara = "";
				}
			}
		}
		return insertParaMap;
		
	}
	
	/**
	* @Title: insertParagraphToDocument
	* @Description: 将段落插入到主文件中
	* @param IBody 主文件
	* @param insertParaMap 匹配好的段落
	* @return void
	*/ 
	private void insertParagraph(IBody document,Map<XWPFParagraph, List<String>> insertParaMap){
		List<XWPFParagraph> paragraphs = document.getParagraphs();
		for (XWPFParagraph paragraph : insertParaMap.keySet()) {
			List<String> valueList = insertParaMap.get(paragraph);
			int myPos = 0;
			for (int i = 0; i < paragraphs.size(); i++) {
				if (paragraph.equals(paragraphs.get(i))) {
					myPos = i;
					break;
				}
			}
			XmlObject xmlObject = null;
			for (int k = 0; k < valueList.size(); k++) {
				if (k == 0) {
					xmlObject = paragraph.getRuns().get(0).getCTR().getRPr()
							.copy();
					while (paragraph.getRuns().size() > 0) {
						paragraph.removeRun(0);
					}
					XWPFRun run = paragraph.createRun();
					run.setText(valueList.get(0));
					CTRPr newrpr = run.getCTR().addNewRPr();
					newrpr.set(xmlObject);
				} else {
					XWPFParagraph newparagraph = null;
					if(document instanceof XWPFDocument){
						if(((XWPFDocument)document).getDocument().getBody()
								.getPArray().length > myPos + k){
							newparagraph = document
									.insertNewParagraph(((XWPFDocument)document).getDocument().getBody()
											.getPArray(myPos + k).newCursor());
						}else{
							newparagraph = ((XWPFDocument) document).createParagraph();
						}
						 
					}else if(document instanceof XWPFTableCell){
						if(((XWPFTableCell)document).getCTTc()
								.getPArray().length > myPos + k){
							newparagraph =  document
									.insertNewParagraph(((XWPFTableCell) document).getCTTc()
									.getPArray(myPos + k).newCursor());
						}else{
							newparagraph = ((XWPFTableCell) document).addParagraph();
						}
						
					}else if(document instanceof XWPFHeaderFooter){
						if(((XWPFHeaderFooter)document)._getHdrFtr()
								.getPArray().length > myPos + k){
							newparagraph = document
									.insertNewParagraph(((XWPFHeaderFooter)document)._getHdrFtr()
											.getPArray(myPos + k).newCursor());
						}else{
							((XWPFHeaderFooter)document).createParagraph();
						}
						
					}
					
					newparagraph.setStyle(paragraph.getStyle());
					newparagraph.setIndentationFirstLine(
							paragraph.getIndentationFirstLine());
					newparagraph.setFontAlignment(paragraph.getFontAlignment());
					XWPFRun run = newparagraph.createRun();
					run.setText(valueList.get(k));
					CTRPr newrpr = run.getCTR().addNewRPr();
					newrpr.set(xmlObject);
				}
			}
		}
	}
	

	
	/**
	* @Title: genRunningParagraph
	* @Description: word中需要不同样式段落操作
	* @param paragraph
	* @param whereClause
	* @return void
	*/ 
	private void genRunningParagraph(XWPFParagraph paragraph,
			Map<String, Object> whereClause) {
		//List<XWPFRun> tmpRuns = new ArrayList<>();
		XWPFRun rpRun = null;
		String tmpVal = "";
		boolean inMatch = false;
		boolean interrupt = false;
		
		for (int j = 0; j < paragraph.getRuns().size(); j++) {
			String re = paragraph.getRuns().get(j).text();
			StringBuffer resb = null;
			if (re != null) {
				resb = new StringBuffer(re);
			} else {
				resb = new StringBuffer();
			}
			if(resb.length() > 0){
				if(resb.substring(resb.length() -1).equals(RUNNING_PREFIX)){
					interrupt = true;
				}
			}
			if (inMatch) {
				tmpVal += resb;
				 paragraph.getRuns().get(j).setText("",0);
				if (resb.toString().indexOf(END_MARK) >= 0) {
					inMatch = false;
					rpRun.setText(tmpVal, 0);
					rpRun = null;
					tmpVal = "";
				}
			}else{
				if(interrupt){
					if(j != paragraph.getRuns().size() - 1){
						String nextRe = paragraph.getRuns().get(j + 1).text();
						if(nextRe != null && nextRe.startsWith(START_MARK)){
							paragraph.getRuns().get(j).setText(paragraph.getRuns().get(j).text() + paragraph.getRuns().get(j+1).text(),0);
							paragraph.getRuns().get(j+1).setText("",0);
						}
					}
					interrupt = false;
				}
				for (int end = 0, start; ((start = resb.toString()
						.indexOf(RUNNING_START_MARK, end)) >= 0);) {
					end = resb.toString().indexOf(END_MARK, start);
					if (end == -1) {
						inMatch = true;
						end = resb.length();
						tmpVal += resb.toString();
						rpRun = paragraph.getRuns().get(j);
					}
				}
			}
		}
		
		
		Map<Integer, String> relacesMap = new HashMap<Integer, String>();
		for (int j = 0; j < paragraph.getRuns().size(); j++) {
			String re = paragraph.getRuns().get(j).text();
			StringBuffer resb = null;
			if (re != null) {
				resb = new StringBuffer(re);
			} else {
				resb = new StringBuffer();
			}
			for (int end = 0, start; ((start = resb.toString()
					.indexOf(RUNNING_START_MARK, end)) >= 0);) {

				end = resb.toString().indexOf(END_MARK, start);
					String key = resb.substring(
							start + RUNNING_START_MARK.length(), end);
					Object value = null;
					if (whereClause.get(key) != null) {
						value = whereClause.get(key);
						// System.out.println(value.getClass().toString());
					}
					if (value == null) {
						value = "";
					};
					resb.replace(start, end + END_MARK.length(),
							value.toString());
					end -= (key.length() + RUNNING_START_MARK.length());
					relacesMap.put(j, resb.toString());
			}
			for (Integer s : relacesMap.keySet()) {
				paragraph.getRuns().get(s).setText(relacesMap.get(s), 0);
			}
		}
		
		
	}


	/**
	* @Title: genPicParagraph
	* @Description: word中图片操作
	* @param document
	* @param paragraph
	* @param imgs
	* @return void
	*/ 
	private void genPicParagraph(CustomXWPFDocument document,
			XWPFParagraph paragraph, Map<String, List<WordImgModel>> imgs) {
		if (imgs != null) {
			String text = paragraph.getText();
			StringBuffer sb = null;
			if (text != null) {
				sb = new StringBuffer(text);
			} else {
				sb = new StringBuffer();
			}
			for (int end = 0, start; ((start = sb.toString()
					.indexOf(PIC_START_MARK, end)) >= 0);) {
				end = sb.toString().indexOf(END_MARK, start);
				String key = sb.substring(start + PIC_START_MARK.length(), end);
				List<WordImgModel> imgList = imgs.get(key);
				if (imgList != null) {
					while (paragraph.getRuns().size() > 0) {
						paragraph.removeRun(0);
					}
					for (int p = 0; p < imgList.size(); p++) {
						WordImgModel img = imgList.get(p);
						try {
							String picId = document.addPictureData(
									img.getInputStream(), img.getPicType());
							document.createPicture(picIndex.get(), picId,
									img.getWidth(), img.getHeight(), paragraph);
							picIndex.set(picIndex.get() + 1);
						} catch (Exception e) {
							e.printStackTrace();
						}
					}
				}
			}
		}
	}

	
	/**
	* @Title: genTables
	* @Description: word中table操作
	* @param tables
	* @param tableParamsMaps
	* @return void
	*/ 
	private void genTables(List<XWPFTable> tables,
			Map<String, ListParamModel> tableParamsMaps,Map<String, ListParamModel> paragraphParamMap,Map<String, Object> whereClause) {
		//int markIndex = 0;
		
		String nowTable = null;
		if (tableParamsMaps != null) {
			for (int i = 0; i < tables.size(); i++) {
				// 获取表格的行
				XWPFTable table = tables.get(i);
				
				List<XWPFTableRow> rows = table.getRows();
				Map<String, TableBaseModel> tableMap = new HashMap<String, TableBaseModel>();
				for (int rowIndex = 0; rowIndex < rows.size();rowIndex++) {
					// 获取表格的每个单元格
					XWPFTableRow row = rows.get(rowIndex);
					List<XWPFTableCell> tableCells = row.getTableCells();
					boolean haslistMark = false;
					for (int j = 0; j < tableCells.size(); j++) {
						StringBuffer text = new StringBuffer(
								tableCells.get(j).getText());
						for (int end = 0, start; ((start = text.toString()
								.indexOf(TABLE_LIST_START_MARK, end)) >= 0);) {
							end = text.toString().indexOf(END_MARK,
									start);
							String key = text.substring(
									start + TABLE_LIST_START_MARK.length(), end);
							ListParamModel lpm =  tableParamsMaps.get(key);
							if(lpm != null){
								haslistMark = true;
								TableBaseModel model = new TableBaseModel();
								model.setTableKey(key);
								model.setListParamModel(lpm);
								tableMap.put(key, model);
								nowTable = key;
							}
							
							text.replace(start, end + END_MARK.length(),
									"");
							end -= (key.length() + TABLE_LIST_START_MARK.length());
						}
						if(haslistMark){
						while (tableCells.get(j).getParagraphs().size() > 1) {
							tableCells.get(j).removeParagraph(0);
						}
						XWPFParagraph ph = tableCells.get(j).getParagraphs().get(0);
						if(ph.getRuns().size() > 0){
						XmlObject xmlObject = ph.getRuns().get(0).getCTR().getRPr()
								.copy();
						while(ph.getRuns().size() > 0){
							ph.removeRun(0);
						}
						XWPFRun run = ph.createRun();
						CTRPr newrpr = run.getCTR().addNewRPr();
						newrpr.set(xmlObject);
						run.setText(text.toString());
						}
						}
					}
					
					boolean hasMark = false;
					for (int j = 0; j < tableCells.size(); j++) {
						// 获取单元格的内容
						StringBuffer text = new StringBuffer(
								tableCells.get(j).getText());
						for (int end = 0, start; ((start = text.toString()
								.indexOf(TABLE_COL_START_MARK, end)) >= 0);) {
							end = text.toString().indexOf(END_MARK,
									start);
							String key = text.substring(
									start + TABLE_COL_START_MARK.length(), end);
							TableBaseModel model = tableMap.get(nowTable);
							if(model == null){
								throw new WordGenException("表格定义错误！");
							}
							model.getColMap().put(j, key);
							hasMark = true;
							text.replace(start, end + END_MARK.length(),
									"");
							end -= (key.length() + TABLE_COL_START_MARK.length());
						}
						if(hasMark){
						while (tableCells.get(j).getParagraphs().size() > 1) {
							tableCells.get(j).removeParagraph(0);
						}
						XWPFParagraph ph = tableCells.get(j).getParagraphs().get(0);
						if(ph.getRuns().size() > 0){
						XmlObject xmlObject = ph.getRuns().get(0).getCTR().getRPr()
								.copy();
						while(ph.getRuns().size() > 0){
							ph.removeRun(0);
						}
						XWPFRun run = ph.createRun();
						CTRPr newrpr = run.getCTR().addNewRPr();
						newrpr.set(xmlObject);
						run.setText(text.toString());
						}
						}
						if (hasMark && tableMap.get(nowTable).getColMap().get(j) == null) {
							tableMap.get(nowTable).getColMap().put(j, null);
						}
						List<XWPFParagraph> paragraphs = tableCells.get(j).getParagraphs();
						for(int k = 0; k < paragraphs.size(); k++){
							genRunningParagraph(paragraphs.get(k), whereClause);
						}
						insertParagraph(tableCells.get(j), genListParagraph(paragraphs, paragraphParamMap,whereClause));
					}
					if(hasMark){
						tableMap.get(nowTable).setMarkRowIndex(rowIndex);
					}
				}
				int tableInsertIndex = 0;
				//直接插入排序
				List<TableBaseModel> sortList = new ArrayList<>();
				for(String tableName: tableMap.keySet()){
					if(sortList.size() == 0){
						sortList.add(tableMap.get(tableName));
					}else if(sortList.size() == 1){
						if(sortList.get(0).getMarkRowIndex() > tableMap.get(tableName).getMarkRowIndex()){
							sortList.add(0,tableMap.get(tableName));
						}else{
							sortList.add(tableMap.get(tableName));
						}
					}else{
						for(int j = 0; j < sortList.size(); j++){
							if(j + 1 != sortList.size()){
								if(sortList.get(j).getMarkRowIndex() <= tableMap.get(tableName).getMarkRowIndex()){
									if(sortList.get(j + 1).getMarkRowIndex() >= tableMap.get(tableName).getMarkRowIndex()){
										sortList.add(j + 1,tableMap.get(tableName));
										break;
									}
								}
							}else{
								sortList.add(tableMap.get(tableName));
								break;
							}
						}
					}
				}
				
				for(int j = 0; j < sortList.size(); j++){
					List<?> list = sortList.get(j).getListParamModel().getParamList();
					Class<?> clazz = sortList.get(j).getListParamModel().getClazz();
					//boolean defaultBorder = false;
					XWPFTableRow borderRow = null;
					if(sortList.get(j).getMarkRowIndex() + tableInsertIndex == table.getRows().size() - 1){
						//defaultBorder = true;
						borderRow = table.getRow(sortList.get(j).getMarkRowIndex() + tableInsertIndex);
					}else{
						borderRow = table.getRow(sortList.get(j).getMarkRowIndex() + tableInsertIndex + 1);
					}
					for (int k = 0; k < list.size(); k++) {
						XWPFTableRow newRow = copy(table,borderRow,sortList.get(j).getMarkRowIndex() + tableInsertIndex + k + 1);
						Object params = list.get(k);
						setTableRow(newRow,sortList.get(j).getColMap(),clazz,params,borderRow);
					}
					tableInsertIndex += list.size();
				}
			}
		}
	}
	
	

 //跨行合并
 public  void mergeCellsVertically(XWPFTable table, int col, int fromRow, int toRow) {  
        for (int rowIndex = fromRow; rowIndex <= toRow; rowIndex++) {  
            XWPFTableCell cell = table.getRow(rowIndex).getCell(col);  
            if ( rowIndex == fromRow ) {  
                // The first merged cell is set with RESTART merge value  
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.RESTART);  
            } else {  
                // Cells which join (merge) the first one, are set with CONTINUE  
                cell.getCTTc().addNewTcPr().addNewVMerge().setVal(STMerge.CONTINUE);  
            }  
        }  
 }
 
 //跨列合并
 public  void mergeCellsHorizontal(XWPFTable table, int row, int fromCell, int toCell) {  
     for (int cellIndex = fromCell; cellIndex <= toCell; cellIndex++) {  
         XWPFTableCell cell = table.getRow(row).getCell(cellIndex);  
         if ( cellIndex == fromCell ) {  
             // The first merged cell is set with RESTART merge value  
             cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.RESTART);  
         } else {  
             // Cells which join (merge) the first one, are set with CONTINUE  
             cell.getCTTc().addNewTcPr().addNewHMerge().setVal(STMerge.CONTINUE);  
         }  
     }  
 } 
 
 //复制行

public XWPFTableRow copy(XWPFTable table,XWPFTableRow sourceRow,int rowIndex){
    //在表格指定位置新增一行
	XWPFTableRow targetRow = table.insertNewTableRow(rowIndex);
	//复制行属性
	targetRow.getCtRow().setTrPr(sourceRow.getCtRow().getTrPr());
	List<XWPFTableCell> cellList = sourceRow.getTableCells();
	if (null == cellList) {
	    return null;
	}
	//复制列及其属性和内容
	XWPFTableCell targetCell = null;
	for (XWPFTableCell sourceCell : cellList) {
	    targetCell = targetRow.addNewTableCell();
	    //列属性
	    targetCell.getCTTc().setTcPr(sourceCell.getCTTc().getTcPr());
	    //段落属性
	    if(sourceCell.getParagraphs()!=null&&sourceCell.getParagraphs().size()>0){                     
	    	targetCell.getParagraphs().get(0).getCTP().setPPr(sourceCell.getParagraphs().get(0).getCTP().getPPr());
            if(sourceCell.getParagraphs().get(0).getRuns()!=null&&sourceCell.getParagraphs().get(0).getRuns().size()>0){
            	XWPFRun cellR = targetCell.getParagraphs().get(0).createRun();
    	        cellR.setText(sourceCell.getText());
    	        cellR.setBold(sourceCell.getParagraphs().get(0).getRuns().get(0).isBold());
            }else{
            	targetCell.setText(sourceCell.getText());
            }
        }else{
        	targetCell.setText(sourceCell.getText());
        }
    }
	return targetRow;
 }
 
 //设置行数据
 public void setTableRow(XWPFTableRow row,Map<Integer, String> keyMap,Class<?> clazz, Object params,XWPFTableRow borderRow){
	 		Field[] fields = clazz.getDeclaredFields();
			for (int col : keyMap.keySet()) {
				Object value = "";
				XWPFTableCell newCell = row.getCell(col);
				XWPFTableCell borderCell = borderRow.getCell(col);
				if (newCell == null) {
					newCell = row.addNewTableCell();
				}
				newCell.getCTTc().setTcPr(borderCell.getCTTc().getTcPr());
				newCell.setColor(borderCell.getColor());
				newCell.setVerticalAlignment(borderCell.getVerticalAlignment());
				for (int k = 0; k < fields.length; k++) {
					try {
						if (fields[k].getName()
								.equals(keyMap.get(col))) {
							Method getter = clazz.getDeclaredMethod(
									"get" + ChangeBean.captureName(
											keyMap.get(col)));
							if (params != null) {
								value = getter.invoke(params);
								newCell.setText(value == null? "":value.toString());
							}
							break;
						}
					} catch (Exception e) {
					}
				}
				/*if(defaultBorder){
					CTTcBorders borders = newCell.getCTTc().addNewTcPr()
							.addNewTcBorders();
					CTBorder vBorder = borders.addNewInsideV();
					vBorder.setVal(STBorder.Enum.forString("single"));
					vBorder.setSz(new BigInteger("4"));
					vBorder.setColor("auto");
					CTBorder lBorder = borders.addNewLeft();
					lBorder.setVal(STBorder.Enum.forString("single"));
					lBorder.setSz(new BigInteger("4"));
					lBorder.setColor("auto");
					CTBorder rBorder = borders.addNewRight();
					rBorder.setVal(STBorder.Enum.forString("single"));
					rBorder.setSz(new BigInteger("4"));
					rBorder.setColor("auto");
					CTBorder tBorder = borders.addNewTop();
					tBorder.setVal(STBorder.Enum.forString("single"));
					tBorder.setSz(new BigInteger("4"));
					tBorder.setColor("auto");
					CTBorder bBorder = borders.addNewBottom();
					bBorder.setVal(STBorder.Enum.forString("single"));
					bBorder.setSz(new BigInteger("4"));
					bBorder.setColor("auto");
					newCell.setText(value == null?"":value.toString());
				}*/
				
			}
		
 }

}
